
/*

DEPENDENCIES:
-------------
Gimme.Effects
ext.get_style
ext.filter
-------------


IN THIS FILE:
-------------
ext.unveil
-------------

*/

Gimme.ext.unveil = function(direction, duration, guid, callback, easing)
{
	var D = Gimme.Effects.Enums.Directions;
	direction = Math.floor(direction) || D[direction] || D.vertically;
	
	function getTo(elem, prop)
	{
		var to = elem['_$gimme$_veil'];
		if (!to)
		{
			to = to || (function()
			{
				// clone for measurement purposes
				var clone = elem.cloneNode(true);
				clone.style.cssText = 'position:absolute;top:0;left:0;visibility:hidden;margin:0;padding:0;border:0;height:;width:;';
				clone.style.display = 'block';						
				elem.parentNode.appendChild(clone);

				clone = Gimme(clone)						
				var h = parseInt(Gimme(elem).get_style('height'), 10) || parseInt(clone.get_style('height'), 10);
				var w = parseInt(Gimme(elem).get_style('width'), 10) || parseInt(clone.get_style('width'), 10);
				clone[0].style.padding = elem.style.padding;

				var rv =
				{
					height: h,
					width: w,
					paddingTop: parseInt(clone.get_style('paddingTop'), 10),
					paddingBottom: parseInt(clone.get_style('paddingBottom'), 10),
					paddingRight: parseInt(clone.get_style('paddingRight'), 10),
					paddingLeft: parseInt(clone.get_style('paddingLeft'), 10)
				};
				
				elem.parentNode.removeChild(clone[0]);
				elem.style.overflow = 'hidden';

				return rv;
			})();
		}
		
		return to[prop];
	}
	
	var D = Gimme.Effects.Enums.Directions;
	direction = Math.floor(direction) || D[direction] || D.vertically;

	var to = {};
	var from = {};
	if ((direction & D.vertically) === D.vertically)
	{
		from.height = from.paddingTop = from.paddingBottom = 0;
		to.height = to.paddingTop = to.paddingBottom = getTo;
	}
	if ((direction & D.horizontally) === D.horizontally)
	{
		from.width = from.paddingLeft = from.paddingRight = 0;
		to.width = to.paddingLeft = to.paddingRight = getTo;
	}
	
	var sb = Gimme.Effects.Storyboard.create
	(
		// items to animate
		this.filter(function(elem)
		{
			var display = elem.style.display || Gimme(elem).get_style('display');
			// Safari 2 will return a null CSSStyleDeclaration object if the element is not currently displayed on the screen
			// Thus, the need for the explicit, display === null check
			return display === 'none' || display === null;
		}),
		
		// from
		from,
		
		//to
		to,
		
		//animate function
		function(elem, props)
		{
			if ((direction & D.vertically) === D.vertically)
			{
				elem.style.height = props.height + 'px';
				elem.style.paddingTop = props.paddingTop + 'px';
				elem.style.paddingBottom = props.paddingBottom + 'px';
			}
			if ((direction & D.horizontally) === D.horizontally)
			{
				elem.style.width = props.width + 'px';
				elem.style.paddingRight = props.paddingRight + 'px';
				elem.style.paddingLeft = props.paddingLeft + 'px';
			}
		},
		
		//durations
		duration,
		
		//guid
		guid,
		
		//callback
		callback,
		
		//easing
		easing || function(t)
		{
			return Gimme.Effects.Easing.Exponential.ease_in_out(t, 4);
		}
	);
	
	sb.get_animations().push
	(
		new Gimme.Effects.Animation(
		{
			startTime: 0,
			elements: this,
			animate: function(elem)
			{
				// make sure contents don't bleed over the element container during the unveiling
				elem.style.overflow = 'hidden';
				
				// make sure we can see it
				elem.style.display = 'block';
			}
		}),
		
		new Gimme.Effects.Animation(
		{
			startTime: sb.get_duration(),
			elements: this,
			animate: function(elem)
			{
				// reset the overflow back to normal once the unveil is done
				elem.style.overflow = '';
			}
		})
	);
	
	sb.begin();
	return this;
};

